#include "StdAfx.h"
#include "ContactSync.h"
#include "../commonlib/Log.h"

ContactSync::~ContactSync(void)
{
}


void ContactSync::Sync(const std::wstring& uri , const std::wstring& userKey , const std::wstring& pwd)
{
	//init
	ATLASSERT(m_app);
	//
	//don't forget to dispose!!!!!!!!!!
	//
	Parser*	parser = new Parser();
	OMSClientBase* client = new OMSClientConcrete();
	std::wstring response;
	//
	//don't forget to dispose!!!!!!!!!!
	//
	std::vector<ContactStruct*>* remotelist = new std::vector<ContactStruct*>();
	std::vector<ContactStruct*>* locallist = new std::vector<ContactStruct*>();
	
	//get remote contact
	if(client->GetContacts(uri,userKey,pwd,response) != 0){
#ifdef _DEBUG
		//MessageBoxW(0,L"remote method GetContacts failed!",L"Error",MB_ICONWARNING);
		LogDebug(_T("remote method GetContacts failed!"));
#endif
		return;
	}
	parser->FindContactResponseList(response,remotelist);

#ifdef FIND_ERROR
			MessageBoxW(0,L"ContactSync::SyncAfterGetResponse",L"",0);
#endif
//	//get outlook local contact list
//	if(GetOutlookLocalContacts(locallist) != 0){
//#ifdef _DEBUG
//		MessageBoxW(0,L"Failed to get local contacts!",L"Error",MB_ICONWARNING);
//#endif
//		return;
//	}

	//begin to sync local contact
	/*
	// name is the key(for local which is fullname)
	// enum the local list , if found the same existed in remote,
	// then replace the local mobile and mark the remote one synced,
	// at last,add the non-synced item in remote list to local one
	*/

	Outlook::_NameSpacePtr ns = m_app->GetNamespace(L"MAPI");
	LogDebug(_T("After GetNamespace"));
	Outlook::MAPIFolderPtr contactFolder = ns->GetDefaultFolder(Outlook::olFolderContacts);
	LogDebug(_T("After GetDefaultFolder"));
	Outlook::_ItemsPtr items = contactFolder->Items;
	long itemCount;
	itemCount= items->GetCount();
	long index = 0;
	std::wstring fullname;
#ifdef FIND_ERROR
			MessageBoxW(0,L"change process begin",L"",0);
#endif
	//change process
	for( long i = 0 ; i < itemCount ; i++ )
	{
		Outlook::_ContactItemPtr item = NULL;
		if(i == 0) item = items->GetFirst();
		else item = items->GetNext();
		LogDebug(_T("After Get _ContactItemPtr"));
		if(item == NULL){
			LogDebug(_T("Get a NULL _ContactItemPtr"));
			continue;
		}
		try{
			if(item->FullName.GetBSTR() != NULL)
				fullname = item->FullName;
			else
				continue;
		}
		catch(...){
			LogDebug(_T("Get a Invalid _ContactItemPtr.FullName"));
			continue;
		}
		//enum remote
		for(std::vector<ContactStruct*>::iterator iter = remotelist->begin();
			iter != remotelist->end();
			iter++)
		{
			//trim first
			if ( trim( (*iter)->Name ).empty()) continue;
			if(_wcsicmp( (*iter)->Name.c_str() , fullname.c_str() ) == 0){
				try{
					item->MobileTelephoneNumber = (*iter)->MobileNumber.c_str();
					item->Save();
					(*iter)->synced = true;
				}
				catch(...){
					LogDebug(_T("Get a Invalid _ContactItemPtr.MobileTelephoneNumber or Save Failed!"));
					continue;
				}
			}
		}
	}

	LogDebug(_T("Begin to add remote contact!"));
	//add process
	Outlook::_ContactItemPtr newItem;
	for(std::vector<ContactStruct*>::iterator iter = remotelist->begin();
		iter != remotelist->end();
		iter++)
	{
		LogDebug((*iter)->Name.c_str());
		if((*iter)->synced == true || trim((*iter)->Name).empty() ) continue;
		newItem = m_app->CreateItem(Outlook::olContactItem);
		if(!newItem) continue;
		//newItem = items->Add(Outlook::olContactItem);
		try{
			newItem->FullName = (*iter)->Name.c_str();
			newItem->MobileTelephoneNumber = (*iter)->MobileNumber.c_str();
			newItem->Save();
		}
		catch(...){
			LogDebug(_T("Invalid _ContactItemPtr.FullName or Invalid _ContactItemPtr.MobileTelephoneNumber or Save Failed when add new contact!"));
			continue;
		}
	}
	

realse:
	//std::vector<ContactStruct*>* remotelist = new std::vector<ContactStruct*>();
	//std::vector<ContactStruct*>* locallist = new std::vector<ContactStruct*>();
	for(std::vector<ContactStruct*>::iterator i = remotelist->begin();
		i != remotelist->end();
		i++){
		delete (*i);
		(*i) = NULL;
	}
	remotelist->clear();
	delete remotelist;
	for(std::vector<ContactStruct*>::iterator i = locallist->begin();
		i != locallist->end();
		i++){
		delete (*i);
		(*i) = NULL;
	}	
	locallist->clear();
	delete locallist;
	//parser
	delete parser;
	delete client;
}


std::wstring&  ContactSync::trim(std::wstring &s) 
{
    if (s.empty()) 
    {
        return s;
    }

    s.erase(0,s.find_first_not_of(L" "));
    s.erase(s.find_last_not_of(L" ") + 1);
    return s;
}